package com.yunxin.core.domain.service.user.impl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.yunxin.core.domain.model.user.*;
import com.yunxin.core.domain.service.user.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.Optional;

/**
 * @author zero°
 * @since 2023-06-02
 */
@DS("core")
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserInfoRepository userInfoRepository;

    private final UserLoginRecordRepository userLoginRecordRepository;

    private final UserAuthRepository userAuthRepository;

    private final UserVisitorInfoRepository userVisitorInfoRepository;

    private final UserIpInfoRepository userIpInfoRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean userRegisterLogin(UserInfo userInfo, String identifierMd5, String loginSource) {
        boolean result = false;
        if (Objects.isNull(userInfo.getId())) {
            userInfo.setMd5Phone(SecureUtil.md5(userInfo.getPhone()));
            userInfo.setPhoneNine(userInfo.getPhone().substring(0,9));
            //保存用户表
            result = userInfoRepository.saveUserInfo(userInfo);
        }
        UserLogin userLogin = UserLogin.builder()
                .userCode(userInfo.getUserCode())
                .loginTime(userInfo.getRegisterTime())
                .city(userInfo.getCity())
                .visitorId(userInfo.getVisitorId())
                .channelPromotionCode(userInfo.getChannelPromotionCode())
                .loginType(0)
                .loginSource(loginSource)
                .build();
        //保存用户登录记录
        saveLoginRecord(userLogin);
        //根据手机号查询用户授权信息
        UserAuth userAuth = userAuthRepository.getUserAuthByIdentifierMd5(identifierMd5);
        if (Objects.nonNull(userAuth) && CharSequenceUtil.isBlank(userAuth.getUserCode())) {
            userAuth.setEditTime(userInfo.getRegisterTime());
            userAuth.setUserCode(userInfo.getUserCode());
            userAuth.setVersion(userAuth.getVersion() + 1);
            //更新用户授权表 - 时间和用户code
            userAuthRepository.updateUserAuth(userAuth);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void userAuthLogin(UserAuth userAuth, String visitorId, String channelPromotionCode, String city, String loginSource) {
        if (Objects.isNull(userAuth.getId())) {
            //向user_auth插入数据
            userAuthRepository.saveUserAuth(userAuth);
        }
        Optional.ofNullable(userAuth.getUserCode()).ifPresent(u -> {
            UserLogin userLogin = UserLogin.builder()
                    .userCode(u)
                    .loginTime(new Date())
                    .city(city)
                    .visitorId(visitorId)
                    .channelPromotionCode(channelPromotionCode)
                    .loginType(1)
                    .loginSource(loginSource)
                    .build();
            //记录用户登录
            saveLoginRecord(userLogin);
        });

    }

    @Override
    public boolean saveUserVisitorInfo(UserVisitorInfo visitorInfo) {
        visitorInfo.setVisitTime(new Date());
        return userVisitorInfoRepository.saveUserVisitorInfo(visitorInfo);
    }

    @Override
    public boolean saveUserIpInfo(UserIpInfo userIpInfo) {
        userIpInfo.setVisitTime(new Date());
        return userIpInfoRepository.saveUserIpInfo(userIpInfo);
    }

    /**
     * 保存登录记录
     * @param userLogin userLogin
     */
    private void saveLoginRecord(UserLogin userLogin){
        UserLoginRecord loginRecord = new UserLoginRecord();
        loginRecord.setUserCode(userLogin.getUserCode());
        loginRecord.setLoginTime(userLogin.getLoginTime());
        loginRecord.setChannelPromotionCode(userLogin.getChannelPromotionCode());
        loginRecord.setLoginCity(userLogin.getCity());
        loginRecord.setVisitorId(userLogin.getVisitorId());
        loginRecord.setLoginSource(userLogin.getLoginSource());
        loginRecord.setLoginType(userLogin.getLoginType());
        userLoginRecordRepository.saveUserLoginRecord(loginRecord);
    }

}
